﻿using System;
using System.IO;
using System.Linq;
using System.Web.UI;
using System.Web.UI.HtmlControls;

namespace FluentTags
{
    public static class Consts
    {
        public static string[] EmptyElements = new string[] { 
            "area", "base", "br", "col", "hr", "img", "input", "link", "meta", "param" };
    }
   
    /// <summary>
    /// Summary description for Tag
    /// </summary>
    public abstract class Tag<T> : HtmlGenericControl
        where T : Tag<T> 
    {

        public Tag(string tag) : base(tag)
        {
        
        }

        public T End()
        {
            return this as T;
        }

        public T AddStyle(string name, string value)
        {
            base.Style.Add(name, value);
            return this as T;
        }

        public new T Style(string style)
        {
            string[] stylePairs = style.Split(';');

            foreach (string stylePair in stylePairs)
            {
                if (String.IsNullOrEmpty(stylePair) == false)
                {
                    if (stylePair.Contains(":"))
                    {
                        string[] s = stylePair.Split(':');

                        base.Style.Add(s[0], s[1]);
                    }
                }
            }
            return this as T;
        }

        /// <summary>
        /// Sets the class, if one already exists it is overwritten
        /// </summary>
        /// <param name="className"></param>
        /// <returns></returns>
        public T Class(string className)
        {
            Attributes.Add("class", className);
            return this as T;
        }

        /// <summary>
        /// Adds a class if one already exists otherwise just sets the class
        /// </summary>
        /// <param name="className"></param>
        /// <returns></returns>
        public T AddClass(string className)
        {
            if (String.IsNullOrEmpty(className))
            {
                return this as T;
            }

            if (Attributes["class"] != null)
            {
                Attributes["class"] += " " + className;
            }
            else
            {
                Class(className);
            }

            return this as T;
        }

        /// <summary>
        /// Sets the ID, if one already exists it is overwritten
        /// </summary>
        /// <param name="className"></param>
        /// <returns></returns>
        public new T ID(string ID)
        {
            base.ID = ID;
            return this as T;
        }

        /// <summary>
        /// Sets the value for the attribute, if one already exists it is overwritten.
        /// 
        /// The attribute will be rendered in the html tag.
        /// 
        /// Examples of attributes: class, style, bgcolor.
        /// </summary>
        /// <param name="attributeName">name of html attribute</param>
        /// <param name="attributeValue">value of html attribute</param>
        /// <returns></returns>
        public T AddAttribute(string attributeName, string attributeValue)
        {
            Attributes.Add(attributeName, attributeValue);
            return this as T;
        }

        /// <summary>
        /// Adds a control to the child controls collection
        /// </summary>
        /// <param name="className"></param>
        /// <returns></returns>
        public T AddControl(Control control)
        {
            Controls.Add(control);
            return this as T;
        }

        /// <summary>
        /// Sets the title, if one already exists it is overwritten
        /// </summary>
        /// <param name="className"></param>
        /// <returns></returns>
        public T Title(string title)
        {
            Attributes.Add("title", title);
            return this as T;
        }

        protected override void Render(HtmlTextWriter writer)
        {
            if(Consts.EmptyElements.Contains(this.TagName.ToLower()))
            {
                writer.WriteBeginTag(TagName);
                RenderAttributes(writer);
                writer.Write(HtmlTextWriter.SelfClosingTagEnd); 
            }
            else
            {
                base.Render(writer);
            }
        }

        public new string ToString()
        {
            TextWriter tw = new StringWriter();
            HtmlTextWriter writer = new HtmlTextWriter(tw);
            RenderControl(writer);
            return tw.ToString();
        }

        protected string SafeString(object value)
        {
            if (value == null)
                return "";
            else
                return value.ToString();
        }

    }

}